// 1. extends 类不仅可以继承类也可以继承构造函数，派生类都有可以通过原型链访问到类和原型上定义的方法

// 2. super 引用原型
class Person{
    constructor(name, age) {
        this.name = name;
        this.age = age;
    };

    static sayHi() {
        console.log('Hi');
    };
};

class Women extends Person{
    constructor(name, age, gender) {
        super(name, age);
        this.gender = gender;
    };

    // 静态方法通过static继承
    static sayHi() {
        super.sayHi();
    };
};

let w1 = new Women('Katrina', 18, 'female');
console.log(w1);
Women.sayHi();   //Hi
    // 1. super只能在派生类和静态方法中使用
    // 2. 不能单独引用super关键字，要么用它调用构造函数，要么引用静态方法
    // 3. super()的行为如同调用构造函数，如果需要给父类构造函数传参，需要手动传入
    // 4. 如果没有定义类构造函数，在实例化派生类时会调用super()，而且会传入所有传给派生类的参数
    // 5. 在类构造函数中，不能调用super()之前引用this
    // 6. 在派生类中显示定义了构造函数，则要么必须在其中调用super()，要么必须在其中返回一个对象

// 3. 抽象基类：可供其他类继承，但是本身不会被实例化

// 4. 继承内置类型

// 5. 类混入
class Vehicle{};

let FooMix = (Superclass) => class extends Superclass{
    foo() {
        console.log('foo');
    };
};

let BarMix = (Superclass) => class extends Superclass{
    bar() {
        console.log('bar');
    };
};

let BazMix = (Superclass) => class extends Superclass{
    baz() {
        console.log('baz');
    };
};

function mix(BaseClass, ...Mixins) {
    return Mixins.reduce((prev, cur)=> cur(prev),BaseClass);
};

class Bus extends mix(Vehicle, FooMix, BarMix, BazMix) {};

let b = new Bus();
b.foo();
b.bar();
b.baz();